#!/bin/sh
# Quick and dirty test that tries different compilers/flags on test programs.

testOutput () # runs $1 and checks if its output gives $2 checksum
{
  echo -n "  testing $1: "

  CS=$(exec $1 | cksum)

  if [ "$CS" = "$2" ]
  then
    echo "OK"
  else
    echo "ERROR"
    exit 1
  fi
}

testError() # tests if running $1 ends with error (1)
{
  echo -n "  testing error behavior $1: "

  OUT=$(exec $1 >/dev/null 2>&1)

  if [ $? = 1 ]
  then
    echo "OK"
  else
    echo "ERROR"
    exit 1
  fi
}

testTranspile() # tests various transpilers
{
  OUT_WC=$(../src_c/a.out test.cmn)

  echo -n "  testing transpilers: "
  ../src_c/a.out -C test.cmn > ~/.tmp/tmp.c

  gcc ~/.tmp/tmp.c

  if [ $? != 0 ]
  then
    echo "ERROR (can't compile C program)"
    exit 0
  fi

  OUT_WC2=$(~/.tmp/a.out)

  if [ "$OUT_WC" != "$OUT_WC2" ]
  then
    echo "ERROR (bad output of C program)"
    exit 0
  fi

  ../src_c/a.out -B -O3 test.cmn > ~/.tmp/tmp.cmb       # comun -> bytecode
  ../src_c/a.out -M -O3 ~/.tmp/tmp.cmb > ~/.tmp/tmp.cmn # bytecode -> comun
  ../src_c/a.out -m ~/.tmp/tmp.cmn > ~/.tmp/tmp2.cmn    # minify
  ../src_c/a.out -b ~/.tmp/tmp2.cmn > ~/.tmp/tmp.cmn    # beautify

  OUT_WC2=$(../src_c/a.out ~/.tmp/tmp.cmn)

  if [ "$OUT_WC" != "$OUT_WC2" ]
  then
    echo "ERROR (bad output of comun program)"
    exit 0
  fi

  echo "OK"
}

echo "========== TESTING =========="

for COMP_CMD in "gcc -O0 comun.c" "gcc -O3 comun.c" "clang -O3 comun.c" "tcc comun.c"
do
  echo "~~~~~~~~~~ COMPILING: $COMP_CMD"
  eval $COMP_CMD

  cd ../programs/

  for COMUN_CMD in "../src_c/a.out -O0" "../src_c/a.out -O3" 
  do
    echo "~~~~~ RUNNING: $COMUN_CMD"

    testOutput "$COMUN_CMD test.cmn" "3679802722 22"
    testOutput "$COMUN_CMD test_bytecode.cmb" "3679802722 22"
    testOutput "$COMUN_CMD test_minicomun.cmn" "2344826656 212"
    testOutput "$COMUN_CMD test_tiny.cmn" "4055255112 8"
    testOutput "$COMUN_CMD test_big.cmn" "1707394586 1202"
    testOutput "$COMUN_CMD test_goto.cmn" "2361246274 158"
    testOutput "$COMUN_CMD -p test_preprocessor.cmn" "1825008481 111"
    testOutput "$COMUN_CMD -p test_preprocessor_include.cmn" "1282779338 187"
    testOutput "$COMUN_CMD test_include.cmn" "3624111326 62"
 
    testError "$COMUN_CMD error_zerodiv.cmn"
    testError "$COMUN_CMD error_premature_end.cmn"
    testError "$COMUN_CMD error_infinite_recursion.cmn"
    testError "$COMUN_CMD error_stack_of.cmn"
    testError "$COMUN_CMD error_bad_tokens.cmn"

    testError "$COMUN_CMD error_bytecode_checksum.cmb"
    testError "$COMUN_CMD error_bytecode_no_end.cmb"
    testError "$COMUN_CMD error_bytecode_opcode.cmb"

    testTranspile
  done

  cd ../src_c
done

echo "~~~~~ TESTING MINICOMUN"

gcc -DSTANDALONE=1 minicomun.h

cd ../programs/

testOutput "../src_c/a.out test_minicomun.cmn" "2344826656 212"
testOutput "../src_c/a.out mandelbrot.cmn" "259290183 2592"
testOutput "../src_c/a.out simple_variables.cmn" "4261122204 23"
testError "../src_c/a.out error_bad_tokens.cmn"
testError "../src_c/a.out error_infinite_recursion.cmn"
testError "../src_c/a.out error_zerodiv.cmn"

echo "ALL SEEMS GOOD"
